package com.wn.main.ui.home

import android.annotation.SuppressLint
import android.graphics.Typeface
import android.util.TypedValue
import android.view.Gravity
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.scwang.smart.refresh.layout.api.RefreshLayout
import com.scwang.smart.refresh.layout.listener.OnRefreshListener
import com.wn.common.model.Banner
import com.wn.common.model.ProjectTabItem
import com.wn.common.provider.SearchServiceProvider
import com.wn.framework.base.BaseFragment
import com.wn.framework.ext.onClick
import com.wn.main.R
import com.wn.main.databinding.FragmentHomeBinding
import com.wn.main.ui.home.adapter.BannerAdapter
import com.wn.main.ui.home.view.HomeTabFragment
import com.wn.main.ui.home.view.HomeVideoFragment
import com.wn.main.ui.home.viewmodel.HomeViewModel
import com.youth.banner.indicator.CircleIndicator
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * @Author: wn
 * @Date: 2024/9/14 16:36
 * @Description: 首页
 */
@AndroidEntryPoint
class HomeFragment : BaseFragment<FragmentHomeBinding>(), OnRefreshListener {

  override fun getLayoutRes() = R.layout.fragment_home

  private val viewModel by viewModels<HomeViewModel>()

  // 轮播图适配器
  @Inject
  lateinit var bannerAdapter: BannerAdapter

  // 选项卡布局中介
  private lateinit var mTabLayoutMediator: TabLayoutMediator

  /**
   * Fragments 数组
   * Android 特有 key value 方式 数组数据
   * put 和 append  保持 index 由小到大排列
   */
/*  private val mArrayTabFragments by lazy {
    SparseArray<Fragment>()
  }*/

  // tabs 集合
/*  private val mProjectTabs by lazy {
    SparseArray<ProjectTabItem>()
  }*/

  override fun initView() {
    super.initView()
    mBinding.apply {
      // 下拉刷新
      refreshLayout.apply {
        // 设置下拉刷新监听器 -- onRefresh 会执行 ,数据请求完成 需要 执行 finishRefresh()
        setOnRefreshListener(this@HomeFragment)
        // 初始化 自动执行 自动刷新,可以设置 延时 或者 只显示动画不执行刷新
        autoRefresh()
        // 是否开启下拉刷新功能（默认true-智能开启）
        // setEnableRefresh(true)
        // 是否开启加上拉加载功能(默认true-智能开启)  --  setOnLoadMoreListener {  }
        setEnableLoadMore(false)
      }

      // 轮播图
      bannerHome.apply {
        addBannerLifecycleObserver(viewLifecycleOwner)
        adapter = bannerAdapter
        indicator = CircleIndicator(context)
      }

      // 这里 为 tab 赋值数据
      tabHome.apply {
        mTabLayoutMediator =
          TabLayoutMediator(this, viewPager) { tab: TabLayout.Tab, position: Int ->
            tab.text = tabs[position].name
          }
        // 设置第一个 tab 效果
        // setTabTextBold(this.getTabAt(0))
        // 增加 tab 选择监听
        addOnTabSelectedListener(tabSelectedCall)
      }
      /**
       * 搜索按钮
       */
      ivSearch.onClick {
        SearchServiceProvider.toSearch(requireContext())
      }
    }
  }

  // 下拉刷新
  override fun onRefresh(refreshLayout: RefreshLayout) {
    refresh()
  }

  /**
   * 初始化获取数据
   * 多次连续的collect导致的问题 : flow没问题,StateFlow 会导致后面的 flow 无法 collect
   * 使用子协程 分别执行各自的 collect 即可
   *
   * loading: StateFlow<Boolean> 重复执行
   */
  private lateinit var job: Job

  private fun refresh() {
    if (::job.isInitialized) job.cancel()
    job = lifecycleScope.launch {
      lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
        // 展示轮播图
        launch {
          viewModel.getHomeBanner().collect {
            it ?: return@collect
            initBanner(it)
          }
        }
        // 加载 tabs 与 viewPager2 Fragment 数据
        launch {
          viewModel.getHomeTabs().collect {
            it ?: return@collect
            initTabAndFragment(it)
          }
        }
      }
    }
  }

  /**
   * 初始化 轮播图
   */
  @SuppressLint("NotifyDataSetChanged")
  private fun initBanner(data: MutableList<Banner>) {
    bannerAdapter.apply {
      list.clear()
      list.addAll(data)
      // 通知数据集已更改
      notifyDataSetChanged()
    }
    // 停止刷新 -- 不设置这个 setOnRefreshListener 可以自动结束
    mBinding.refreshLayout.finishRefresh()
  }

  /**
   * 加载 tabs 与 viewPager2 Fragment 数据
   * 这里 必须保持 刷新后 数据的个数相同 才会被 完全替换掉
   * 否则 需要 先 clear 然后 在这里 由 index-0 开始全部初始化
   */
  val tabs = mutableListOf<ProjectTabItem>()
  private fun initTabAndFragment(data: MutableList<ProjectTabItem>) {
    tabs.clear()
    tabs.add(0, ProjectTabItem(0, getString(com.wn.framework.R.string.home_tab_video_title)))

    data.forEachIndexed { index, projectTabItem ->
      tabs.add(index + 1, projectTabItem)
    }

    mBinding.apply {
      /**
       * 问题所在
       */
      viewPager.adapter = object : FragmentStateAdapter(this@HomeFragment) {

        override fun getItemCount() = tabs.size

        override fun createFragment(position: Int): Fragment =
          if (position == 0)
            HomeVideoFragment()
          else
            HomeTabFragment.newInstance(tabs[position].id)

      }
      // 禁用预加载
      viewPager.offscreenPageLimit = 1

      // tabLayout 和 viewPager2 关联起来  这个必须在 viewPager设置 adapter之后
      if (::mTabLayoutMediator.isInitialized && !mTabLayoutMediator.isAttached) mTabLayoutMediator.attach()

      // 解决 TabLayout 下拉刷新后滚动到错误位置 -- 指定第一个选中
      // tabHome.getTabAt(0)?.select()
    }
  }

  /**
   * 设置 tab 大小加粗 变黑 效果
   */
  private fun setTabTextBold(tabFirst: TabLayout.Tab?) {
    TextView(context).apply {
      typeface = Typeface.DEFAULT_BOLD
      setTextSize(TypedValue.COMPLEX_UNIT_SP, 16f)
      setTextColor(context.getColor(com.wn.framework.R.color.color_222427))
      gravity = Gravity.CENTER
      text = tabFirst?.text
      tabFirst?.customView = this
    }
  }

  /**
   * tab选择回调
   */
  private val tabSelectedCall = object : TabLayout.OnTabSelectedListener {
    override fun onTabSelected(tab: TabLayout.Tab?) {
      setTabTextBold(tab)
    }

    override fun onTabUnselected(tab: TabLayout.Tab?) {
      // 非选中效果在xml中设置
      tab?.customView = null
    }

    override fun onTabReselected(tab: TabLayout.Tab?) {
    }
  }

  /**
   * Home键或者锁屏 后 数据重复请求  -- stop
   * viewPager 滑动 -- pause
   */
  override fun onStop() {
    if (::job.isInitialized) job.cancel()
    super.onStop()
  }

  override fun onDestroy() {
    super.onDestroy()
    if (::mTabLayoutMediator.isInitialized) mTabLayoutMediator.detach()
  }
}